<template style="background-color: #f6f6f6">
  <el-card class="box-card">
    <template #header>
      <div class="card-header">
        <span>会议文件</span>
        <span style="float: right">
          <!-- <div id="uploader" class="upload-container" style="width: 100px"> -->
          <!-- 文件列表区域 -->
          <!-- <div id="thelist" class="file-list"> -->
          <!-- 文件项将通过JS动态添加到这里 -->
          <!-- </div> -->

          <!-- <el-button id="picker">
      <i class="el-icon-upload"></i>
      <span>选择文件上传</span>
    </el-button> -->
          <!-- </div> -->
          <div
            style="
              display: inline-block;

              border-radius: 4px;
              overflow: hidden;

              cursor: pointer;
              margin-right: 20px;
            "
          >
            <button
              class="upload-button"
              @click="selectFile"
              style="padding: 10px; font-size: 15px"
            >
              普通上传
            </button>
            <input
              type="file"
              ref="fileInput"
              style="display: none"
              @change="uploadFile"
            />
            <!-- <div style="color: #409eff; padding: 10px">普通上传</div> -->
          </div>

          <div
            style="
              display: inline-block;
              border: 1px solid #409eff;
              border-radius: 4px;
              overflow: hidden;
              background-color: #f0f8ff;
              cursor: pointer;
            "
          >
            <div style="float: left; color: #409eff; padding: 7px">
              分片上传
            </div>
            <el-button
              id="picker"
              class="upload-btn"
              style="border: none; background-color: transparent; padding: 10px"
            >
              <i class="el-icon-upload"></i>
              <span style="margin-left: 5px"></span>
            </el-button>
          </div>

          <!-- <el-button @click="uploadFiles" class="btn btn-default"
        >开始上传</el-button
      > -->

          <!-- <upload :meeting-id="meetingId" :user-id="userId"></upload> -->
        </span>
      </div>
    </template>

    <div style="height: 70%">
      <el-table
        v-loading="tableLoading"
        row-key="fileId"
        :data="filterData"
        style="width: 100%; height: 80%"
        border
        stripe
      >
        <el-table-column
          prop="fileName"
          label="文件名"
          width="150"
          align="center"
        />
        <el-table-column prop="fileType" label="类型" align="center" />
        <el-table-column
          prop="fileSize"
          label="文件大小"
          width="150"
          align="center"
        />

        <el-table-column
          prop="uploadTime"
          label="上传日期"
          width="150"
          align="center"
        />
        <el-table-column
          prop="description"
          label="文件描述"
          width="150"
          align="center"
        />
        <el-table-column
          prop="isDownload"
          label="是否可下载"
          width="150"
          align="center"
        >
          <template v-slot="scope">
            <el-tag
              :type="scope.row.isDownload === 101 ? 'success' : 'danger'"
              disable-transitions
              >{{ scope.row.isDownload === 101 ? "是" : "否" }}
            </el-tag>
          </template>
        </el-table-column>
        <!-- <el-table-column
          prop="isAnnotation"
          label="是否可批注"
          width="150"
          align="center"
        >
          <template v-slot="scope">
            <el-tag
              :type="scope.row.isAnnotation === 102 ? 'success' : 'danger'"
              disable-transitions
              >{{ scope.row.isAnnotation === 102 ? "是" : "否" }}
            </el-tag>
          </template>
        </el-table-column> -->
        <el-table-column fixed="right" label="操作" width="200" align="center">
          <template #default="scope">
            <el-button
              size="small"
              type="primary"
              @click="previewFile(scope.row.fileName)"
              >预览</el-button
            >

            <el-button
              size="small"
              type="primary"
              @click="startDownload(scope.row.fileName)"
              >下载</el-button
            >
            <el-button
              size="small"
              type="danger"
              @click="deleteFile(scope.row.fileId, scope.row.fileName)"
              >删除</el-button
            >
            <!-- <el-button size="small" type="warning" @click="editFile(scope.row)"
              >修改</el-button
            >-->
          </template>
        </el-table-column>
      </el-table>
    </div>
  </el-card>
  <!-- <el-dialog :visible.sync="this.editDialogVisible" title="修改文件信息">
    <el-form :model="editForm">
      <el-form-item label="文件名" :label-width="formLabelWidth" disabled>
        <el-input v-model="editForm.fileName" disabled></el-input>
      </el-form-item>
      <el-form-item label="类型" :label-width="formLabelWidth" disabled>
        <el-input v-model="editForm.fileType" disabled></el-input>
      </el-form-item>
      <el-form-item label="文件大小" :label-width="formLabelWidth" disabled>
        <el-input v-model="editForm.fileSize" disabled></el-input>
      </el-form-item>
      <el-form-item label="上传日期" :label-width="formLabelWidth" disabled>
        <el-input v-model="editForm.uploadTime" disabled></el-input>
      </el-form-item>
      <el-form-item label="文件描述" :label-width="formLabelWidth">
        <el-input v-model="editForm.description"></el-input>
      </el-form-item>
      <el-form-item label="是否可下载" :label-width="formLabelWidth">
        <el-select v-model="editForm.isDownload" placeholder="请选择">
          <el-option label="是" value="101"></el-option>
          <el-option label="否" value="102"></el-option>
        </el-select>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="editDialogVisible = false">取 消</el-button>
      <el-button type="primary" @click="updateFile">确 定</el-button>
    </span>
  </el-dialog> -->
</template>

<script>
import WebUploader from "webuploader";

import $ from "jquery";
import upload from "./upload.vue";
import moment from "moment";
import { ElMessage } from "element-plus";
import axios from "axios";
import * as XLSX from "xlsx";
export default {
  components: {
    upload,
  },
  data() {
    return {
      uploader: null,

      meetingId: "",
      userId: "",
      current: 1,
      pageCount: 0,
      tableData: [],
      tableLoading: false,
      search: "",
      //fileName: "pdfTest.pdf", // 输入的文件名
      chunkSize: 5 * 1024 * 1024, // 分片大小，50MB
      totalSize: 0, // 文件的总大小
      downloadedChunks: [], // 存储下载的分片
      currentChunk: 0, // 当前下载的分片索引
      editDialogVisible: false,
      editForm: {
        fileId: "",
        fileName: "",
        fileType: "",
        fileSize: "",
        uploadTime: "",
        description: "",
        isDownload: "",
      },
      formLabelWidth: "120px",
      loading: false,
    };
  },
  mounted() {
    this.initializeUploader();
  },
  computed: {
    filterData() {
      return this.tableData.filter((data) => {
        return (
          !this.search ||
          (data.name != null &&
            data.name.toLowerCase().includes(this.search.toLowerCase())) ||
          data.id === this.search
        );
      });
    },
  },
  methods: {
    initTable(meetingId, userId) {
      this.tableLoading = true;
      this.meetingId = meetingId;
      this.userId = userId;
      this.$http
        .get("/file/file/getMeetingFile?meetingId=" + this.meetingId)
        .then((response) => {
          console.log(this.meetingId);
          console.log(response);
          if (response.data.code === 200) {
            this.tableData = response.data.data;
            for (let i = 0; i < this.tableData.length; i++) {
              this.tableData[i].uploadTime = moment(
                this.tableData[i].uploadTime
              ).format("YYYY-MM-DD");
              this.tableData[i].fileSize = this.tableData[i].fileSize + "kb";
            }
            this.tableLoading = false;
          }
        });
    },
    async previewFile(fileName) {
      try {
        const response = await axios.get("/file/file/getPresignedUrl", {
          params: { fileName },
        });
        if (response.data.code === 200) {
          const presignedUrl = response.data.data.url;
          const fileExtension = fileName.split(".").pop().toLowerCase();

          if (
            fileExtension === "pdf" ||
            fileExtension === "doc" ||
            fileExtension === "docx" ||
            fileExtension === "xlsx" ||
            fileExtension === "xls"
          ) {
            // 使用 Google Docs Viewer 预览文件
            const viewerUrl = `https://docs.google.com/gview?url=${encodeURIComponent(
              presignedUrl
            )}&embedded=true`;
            window.open(viewerUrl, "_blank");
          } else {
            // 对于其他文件类型，尝试直接在新标签页中打开
            window.open(presignedUrl, "_blank");
          }
        } else {
          ElMessage.error(response.data.msg);
        }
      } catch (error) {
        ElMessage.error("预览文件失败");
      }
    },
    async deleteFile(fileId, fileName) {
      try {
        const response = await this.$http.delete(
          `/file/file/deleteInfoById?idList=${fileId}`
        );
        if (response.data.code === 200) {
          await this.$http.delete(`/file/file/delete?fileName=${fileName}`);
          this.initTable(this.meetingId, this.userId);
          ElMessage({ message: "删除成功！", type: "success" });
        } else {
          ElMessage.error(response.data.msg);
        }
      } catch (error) {
        ElMessage.error("删除文件失败");
      }
    },
    async startDownload(downFileName) {
      if (!downFileName) {
        alert("Please enter a file name.");
        return;
      }

      //获取文件的总大小;
      // const metaDataResponse = await this.$http.get(
      //   `/file/file/fileMetaData?filename=${this.fileName}`
      // );
      const params = { filename: downFileName };
      const metaDataResponse = await this.$http.get("/file/file/fileMetaData", {
        params,
      });

      // const metaDataResponse = await this.$http.get("/file/file/fileMetaData", {
      //   params: this.fileName,
      // });
      this.totalSize = metaDataResponse.data.data.fileSize;

      // 计算分片数量
      const totalChunks = Math.ceil(this.totalSize / this.chunkSize);

      // 构建所有分片下载任务
      const downloadTasks = [];
      for (let i = 0; i < totalChunks; i++) {
        downloadTasks.push(this.downloadChunk(i, downFileName));
      }

      // 并行下载所有分片
      await Promise.all(downloadTasks);

      // 合并分片
      this.mergeChunks(downFileName);
    },

    async downloadChunk(index, downFileName) {
      const start = index * this.chunkSize;
      const end = Math.min(start + this.chunkSize - 1, this.totalSize - 1);
      const range = `bytes=${start}-${end}`;
      console.log("Downloading range:", range);

      try {
        // const response = await this.$http.get(`/file/fileDownload`, {
        //   params: {
        //     filename: this.fileName,
        //     range: range,
        //   },
        //   responseType: "blob",
        // });

        const url = `/file/file/fileDownload?filename=${downFileName}&range=bytes=${start}-${end}`;
        const response = await this.$http.get(url, {
          responseType: "blob",
        });

        if (response.data.size !== end - start + 1) {
          console.error(`Chunk ${index} downloaded with incorrect size`);
          throw new Error(`Chunk ${index} downloaded with incorrect size`);
        }

        this.downloadedChunks[index] = response.data;
        console.log(`Chunk ${index} downloaded successfully`);
        this.currentChunk = index + 1;
      } catch (error) {
        console.error("Error downloading chunk:", error);
        // 重试下载
        this.downloadChunk(index);
      }
    },

    mergeChunks(downFileName) {
      if (
        this.downloadedChunks.length !==
        Math.ceil(this.totalSize / this.chunkSize)
      ) {
        console.error("Not all chunks are downloaded");
        return;
      }

      const blob = new Blob(this.downloadedChunks, {
        type: "application/octet-stream",
      });
      const link = document.createElement("a");
      link.href = URL.createObjectURL(blob);
      link.download = downFileName;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    },
    initializeUploader() {
      // HOOK 必须在 uploader 实例化前
      WebUploader.Uploader.register(
        {
          "before-send-file": "beforeSendFile",
          "before-send": "beforeSend",
        },
        {
          beforeSendFile: (file) => {
            const task = new Promise((resolve, reject) => {
              this.uploader
                .md5File(file)
                .progress((percentage) => {
                  console.log("计算md5进度:", percentage);
                  this.getProgressBar(file, percentage, "MD5", "MD5进度");
                })
                .then((val) => {
                  console.log("md5 result:", val);
                  file.md5 = val;
                  file.uid = WebUploader.Base.guid();
                  const formData = new FormData();
                  formData.append("md5", file.md5);
                  this.$http
                    .post("/file/file/checkFileMd5", formData)
                    .then((response) => {
                      const status = response.data.data.status.value;

                      if (status === 101) {
                        console.log(1111);
                        resolve(); // 文件不存在，那就正常流程
                      } else if (status === 100) {
                        this.uploader.skipFile(file);
                        file.pass = true;
                        resolve(); // 忽略上传过程，直接标识上传成功
                      } else if (status === 102) {
                        file.missChunks = response.data.data.data; // 部分已经上传到服务器了
                        resolve();
                      }
                    })
                    .catch((error) => {
                      console.error(error);
                      reject();
                    });
                });
            });
            return task;
          },
          beforeSend: (block) => {
            const task = new Promise((resolve, reject) => {
              const file = block.file;
              const missChunks = file.missChunks;
              const blockChunk = block.chunk;
              console.log("当前分块：" + blockChunk);
              console.log("missChunks:" + missChunks);
              if (missChunks && missChunks.length > 0) {
                if (missChunks.includes(blockChunk)) {
                  console.log(
                    file.name + ":" + blockChunk + ":还没上传，现在上传去吧。"
                  );
                  resolve();
                } else {
                  reject();
                }
              } else {
                resolve();
              }
            });
            return task;
          },
        }
      );

      // 实例化 WebUploader
      this.uploader = WebUploader.create({
        pick: {
          id: "#picker",
          label: "",
        },
        formData: {
          uid: 0,
          md5: "",
          chunkSize: this.chunkSize,
        },
        swf: "js/Uploader.swf",
        chunked: true,
        chunkSize: this.chunkSize, // 字节 5M分块
        threads: 10,
        //server: "http://localhost:18084/file/fileUpload", // 更新端口号为 8084
        server: "https://nacos.inquark.com:66/api/file/file/fileUpload",
        //server: "http://localhost:8084/file/fileUpload_IsAnnotation_IsDownload", // 更新端口号为 8084
        auto: true,
        disableGlobalDnd: true,
        fileNumLimit: 1024,
        fileSizeLimit: 10 * 1024 * 1024 * 1024, // 10 GB
        fileSingleSizeLimit: 1024 * 1024 * 1024, // 1 GB
      });

      // 事件处理
      this.uploader.on("fileQueued", (file) => {
        console.log("fileQueued");
        const maxSize = 50 * 1024 * 1024; // 50MB

        if (file.size < maxSize) {
          this.uploader.removeFile(file, true); // 移除文件
          ElMessage.warning("文件小于50MB，请使用普通上传功能");
          return;
        }
        $("#thelist").append(`<div id="${file.id}" class="item">
          <h4 class="info">${file.name}</h4>
          <p class="state">等待上传...</p>
        </div>`);
      });

      this.uploader.onUploadBeforeSend = (obj, data) => {
        this.tableLoading = true;
        console.log("onUploadBeforeSend");
        const file = obj.file;
        data.md5 = file.md5 || "";
        data.uid = file.uid;
      };

      this.uploader.on("uploadProgress", (file, percentage) => {
        this.getProgressBar(file, percentage, "FILE", "上传进度");
      });

      this.uploader.on("uploadSuccess", (file) => {
        this.tableLoading = false;

        ElMessage({ message: "大文件分片上传成功！", type: "success" });

        let text = "已上传";
        if (file.pass) {
          text = "文件秒传功能，文件已上传。";
        }
        $("#" + file.id)
          .find("p.state")
          .text(text);

        // 获取文件格式
        const fileFormat = this.getFileFormat(file.name);
        const fileSizeInKB = Math.floor(file.size / 1024);
        console.log(fileSizeInKB);
        // 调用 insertFile 接口
        this.insertFile({
          userId: this.userId,
          meetingId: this.meetingId,
          fileName: file.name,
          fileSize: fileSizeInKB,
          fileType: fileFormat,
        });
      });

      this.uploader.on("uploadError", (file) => {
        $("#" + file.id)
          .find("p.state")
          .text("上传出错");
      });

      this.uploader.on("uploadComplete", (file) => {
        this.fadeOutProgress(file, "MD5");
      });
    },
    insertFile(params) {
      axios
        .post("https://nacos.inquark.com:66/api/file/file/insertFile", params, {
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
        })
        .then((response) => {
          this.initTable(this.meetingId, this.userId);
          console.log("Insert operation successful:", response.data);
        })
        .catch((error) => {
          console.error("Error during insert operation:", error);
        });
    },
    getFileFormat(fileName) {
      // 查找文件名中最后一个点（.）的位置
      const dotIndex = fileName.lastIndexOf(".");
      if (dotIndex > 0) {
        // 如果存在点，返回点之后的部分作为文件格式
        return fileName.substring(dotIndex + 1).toLowerCase();
      } else {
        // 如果不存在点，返回空字符串或默认值
        return "";
      }
    },
    uploadFiles() {
      console.log("上传...");
      this.uploader.upload();
      console.log("上传成功");
    },
    getProgressBar(file, percentage, idPrefix, titleName) {
      const $li = $("#" + file.id);
      let $percent = $li.find("#" + idPrefix + "-progress-bar");
      if ($percent.length === 0) {
        $percent =
          $(`<div id="${idPrefix}-progress" class="progress progress-striped active">
          <div id="${idPrefix}-progress-bar" class="progress-bar" role="progressbar" style="width: 0%"></div>
        </div>`)
            .appendTo($li)
            .find("#" + idPrefix + "-progress-bar");
      }
      const progressPercentage = Math.ceil(percentage * 100) + "%";
      $percent.css("width", progressPercentage);
      $percent.html(`${titleName}:${progressPercentage}`);
    },
    fadeOutProgress(file, idPrefix) {
      $("#" + file.id)
        .find("#" + idPrefix + "-progress")
        .fadeOut();
    },
    selectFile() {
      this.$refs.fileInput.click();
    },
    uploadFile() {
      const fileInput = this.$refs.fileInput;
      const file = fileInput.files[0];
      if (!file) {
        alert("请选择一个文件");
        return;
      }

      const formData = new FormData();
      formData.append("multipartFile", file);
      this.tableLoading = true;
      fetch("https://nacos.inquark.com:66/api/file/file/up", {
        method: "POST",
        body: formData,
      }).then((response) => {
        this.tableLoading = false;

        ElMessage({ message: "上传成功！", type: "success" });
        const fileFormat = this.getFileFormat(file.name);
        const fileSizeInKB = Math.floor(file.size / 1024);
        // 调用 insertFile 接口
        this.insertFile({
          userId: this.userId,
          meetingId: this.meetingId,
          fileName: file.name,
          fileSize: fileSizeInKB,
          fileType: fileFormat,
        });
        // return response.json(); // 尝试解析JSON
      });
      // .then((data) => {
      //   console.log("Success:", data);
      //   alert("文件上传成功");
      // })
      // .catch((error) => {
      //   console.error("Error:", error);
      //   if (error.message.includes("Unexpected token")) {
      //     alert("服务器返回的响应不是有效的JSON格式");
      //   } else {
      //     alert("文件上传失败");
      //   }
      // });
    },
    editFile(file) {
      console.log(1111);

      this.editForm = {
        fileId: file.fileId,
        fileName: file.fileName,
        fileType: file.fileType,
        fileSize: file.fileSize,
        uploadTime: file.uploadTime,
        description: file.description,
        isDownload: file.isDownload.toString(),
      };
      this.editDialogVisible = true;
    },

    // 更新文件信息并关闭对话框
    updateFile() {
      const updateData = {
        fileId: this.editForm.fileId,
        description: this.editForm.description,
        isDownload: parseInt(this.editForm.isDownload),
      };

      axios
        .put("/file/updateFile", updateData)
        .then((response) => {
          if (response.data.code === 200) {
            ElMessage.success("文件信息更新成功");
            this.editDialogVisible = false;
            this.initTable(this.meetingId, this.userId); // 重新加载表格数据
          } else {
            ElMessage.error(response.data.msg || "文件信息更新失败");
          }
        })
        .catch((error) => {
          console.error("Error updating file:", error);
          ElMessage.error("文件信息更新失败");
        });
    },
  },
};
</script>

<style scoped>
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.box-card {
  height: 94%;
}
.upload-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
  widows: 10px;
  border-radius: 8px;
  background-color: #f8fafc;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

/* 上传按钮样式 */
.upload-btn {
  width: 10%;
  height: 40px;
  background-color: #66b1ff;
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 14px;
  transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.upload-btn:hover {
  background-color: #66b1ff;
  /* transform: translateY(-2px); */
  /* box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3); */
}
.upload-btn:active {
  transform: translateY(1230);
}

/* 文件列表样式 */
.file-list {
  width: 100%;
  max-height: 300px;
  overflow-y: auto;
  border-radius: 6px;
  background-color: white;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  padding: 8px;
}

.file-list .item {
  padding: 12px 16px;
  border-bottom: 1px solid #ebeef5;
  transition: background-color 0.2s;
}

.file-list .item:hover {
  background-color: #f5f7fa;
}

.file-list .info {
  margin: 0 0 6px 0;
  font-size: 14px;
  color: #303133;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.file-list .state {
  margin: 0;
  font-size: 12px;
  color: #909399;
}

/* 进度条样式 */
.progress {
  height: 8px;
  margin-top: 10px;
  border-radius: 4px;
  background-color: #ebeef5;
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  background: linear-gradient(90deg, #409eff, #66b1ff);
  transition: width 0.3s ease;
  position: relative;
}

.progress-bar::after {
  content: attr(data-progress);
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 10px;
  color: white;
}

/* 滚动条样式 */
.file-list::-webkit-scrollbar {
  width: 6px;
}

.file-list::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.file-list::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.file-list::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}
.upload-button {
  display: inline-block;
  border: 1px solid #409eff;
  border-radius: 4px;
  overflow: hidden;
  background-color: #f0f8ff;
  cursor: pointer;
  margin-right: 20px;
  padding: 10px;
  color: #409eff;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .upload-container {
    padding: 12px;
  }

  .upload-btn {
    height: 36px;
    font-size: 13px;
  }

  .file-list .item {
    padding: 10px 12px;
  }
}
</style>
